package wh.iolists;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import org.json.JSONException;

import wh.Order;
import wh.ProcessedOrder;
import wh.exceptions.BadIDFormat;
import wh.exceptions.IDCollisionException;
import wh.exceptions.MissingReferenceException;
import wh.guistuff.SwingInitializations;
import wh.myjson.JAOrder;
import wh.myjson.JAStorageDisk;
import wh.myjson.JSONOrder;
import wh.myjson.JSONStorageDisk;
import wh.products.StorageDisk;

/**
 * Contains datastructures and functionality for dealing with Orders
 * @author Geir
 *
 */
public class OrderList
{
    // Storage for an arbitrary number of details.
    private static ArrayList <Order> orderList;
    private static OrderList instance = null; // Singleton purpose
    
    ////////Singleton part Begin //////////////
	
    protected OrderList() {
    	// Exists only to defeat instantiation.
    }

    public static OrderList getInstance() {

    	if (instance == null)
    	{
    		instance = new OrderList();
    	}
    	return instance;
    }
    ///////// Singleton part End ////////////////
    
    /**
     * Perform any initialization .
     */
    public void doInitializations()
    {
    	orderList = new ArrayList<Order>();
    	restoreOrders(); // Loads the orders from text file
    }
    
    /**
     * Add a new set of details to the list
     * @param details The details of the staff
     */
    public void addDetails(Order details) 
    {
    	orderList.add(details);
    }
    
    public Order getOrder(int index)
    {
    	return orderList.get(index);
    }
    
    public Order getOrder(String id)
    {
    	for (Order order : orderList)
    	{
    		if (order.getProductID().equalsIgnoreCase(id))
    			return order;
    	}
    	return null;
    }
    
    public synchronized Order getAvailableOrder()
    {
    	for (Order order : orderList)
    	{
    		if (order.isBusyProcessing() == false) // Is not busy, fetch it
    		{
    			order.setIsBusyProcessing(true); // Used later to check if order is being handled, before selecting one that is free
    			return order;
    		}
    	}
    	return null;
    }
    
    public synchronized void removeOrder(String orderID)
    {
    	for (Order order : orderList)
    	{
    		if (order.getOrderID().equalsIgnoreCase(orderID))
    		{
    			orderList.remove(order);
    			break;
    		}
    	}
    }
    
    public synchronized void removeOrder(Order order)
    {
    	if (orderList.contains(order))
    		orderList.remove(order);
    }
    
    public int getOrderListSize() {
    	return orderList.size();
    }
    
    public boolean hasOrder() {
    	return orderList.size() > 0;
    }
    

    /**
     * @return All the details
     */
    public String listDetails()
    {
    	StringBuffer allEntries = new StringBuffer();
    	for (Order details : orderList) {
            allEntries.append(details.getOrderID() );
            allEntries.append('\n');
        }
        return allEntries.toString();
    }
    
    /**
     * Loads the orders into the application from Orders.txt. From JSON to ArrayList
     */
    private void restoreOrders()
	{
		try {
            
            FileReader fileReader = new FileReader(new File("Orders.txt"));
            BufferedReader buffR = new BufferedReader(fileReader);
            
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = buffR.readLine()) != null) {
                sb.append(line);
            }
            
            JAOrder ja = new JAOrder(sb.toString());
            
            for (int i = 0; i < ja.length(); i++) {
                
            	JSONOrder jo = new JSONOrder(ja.get(i).toString());
            	
            	orderList.add(createOrder(jo));
            }
            
        } catch (JSONException ex) {
        	ex.printStackTrace();
        } catch (FileNotFoundException ex) {
        	ex.printStackTrace();
        } 
        catch (IOException ex) {
        	ex.printStackTrace();
        }
		System.out.println("amount of products: "+orderList.size());
	}
    
    private Order createOrder(JSONOrder jo)
	{
    	Order sd = null;
		try {
			sd = new Order(jo.getString("oID"), jo.getString("customerID"), jo.getString("productID"), jo.getInt("quantity"));
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (BadIDFormat e) {
			
			// sd = createNewUniqueID(jo);
			
		} catch (IDCollisionException e) {
			
			// sd = createNewUniqueID(jo);
			
		} catch (MissingReferenceException e) {
			
			// notify user and log it
		}
		return sd;
	}
    
    private Order createNewUniqueID(JSONOrder jo)
    {
    	return null;
    }
}
